/* Copyright (c) 2010-2013 The Trustees of Indiana University.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * - Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 * 
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * 
 * - Neither the Indiana University nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without
 *   specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
//#include "nbc.h"
#include <stdint.h>
#include <mpi.h>
 
/* Function return codes  */
#define NBC_OK 0 /* everything went fine */
#define NBC_SUCCESS 0 /* everything went fine (MPI compliant :) */
#define NBC_OOR 1 /* out of resources */
#define NBC_BAD_SCHED 2 /* bad schedule */
#define NBC_CONTINUE 3 /* progress not done */
#define NBC_DATATYPE_NOT_SUPPORTED 4 /* datatype not supported or not valid */
#define NBC_OP_NOT_SUPPORTED 5 /* operation not supported or not valid */
#define NBC_NOT_IMPLEMENTED 6
#define NBC_INVALID_PARAM 7 /* invalid parameters */
#define NBC_INVALID_TOPOLOGY_COMM 8 /* invalid topology attached to communicator */


/****************** THIS FILE is automatically generated *********************
 * changes will be deleted at the next generation of this file - see nbc_op.c.m4 */

int NBC_Operation(void *buf3, void *buf1, void *buf2, MPI_Op op, MPI_Datatype type, int count) {
  int i;
     
  if(type == MPI_INT) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((int*)buf1) + i) > *(((int*)buf2) + i)) *(((int*)buf3) + i) = *(((int*)buf2) + i); else *(((int*)buf3) + i) = *(((int*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((int*)buf1) + i) < *(((int*)buf2) + i)) *(((int*)buf3) + i) = *(((int*)buf2) + i); else *(((int*)buf3) + i) = *(((int*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((int*)buf3) + i) = *(((int*)buf1) + i) + *(((int*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((int*)buf3) + i) = *(((int*)buf1) + i) * *(((int*)buf2) + i); 
      }
    } else if(op == MPI_LAND) {
      for(i=0; i<count; i++) {
        *(((int*)buf3) + i) = *(((int*)buf1) + i) && *(((int*)buf2) + i); 
      }
    } else if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((int*)buf3) + i) = *(((int*)buf1) + i) & *(((int*)buf2) + i); 
      }
    } else if(op == MPI_LOR) {
      for(i=0; i<count; i++) {
        *(((int*)buf3) + i) = *(((int*)buf1) + i) || *(((int*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((int*)buf3) + i) = *(((int*)buf1) + i) | *(((int*)buf2) + i); 
      }
    } else if(op == MPI_LXOR) {
      for(i=0; i<count; i++) {
        *(((int*)buf3) + i) = ((*(((int*)buf1) + i) ? 1 : 0) ^ (*(((int*)buf2) + i) ?  1 : 0)); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((int*)buf3) + i) = ((*(((int*)buf1) + i)) ^ (*(((int*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_LONG) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((long*)buf1) + i) > *(((long*)buf2) + i)) *(((long*)buf3) + i) = *(((long*)buf2) + i); else *(((long*)buf3) + i) = *(((long*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((long*)buf1) + i) < *(((long*)buf2) + i)) *(((long*)buf3) + i) = *(((long*)buf2) + i); else *(((long*)buf3) + i) = *(((long*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((long*)buf3) + i) = *(((long*)buf1) + i) + *(((long*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((long*)buf3) + i) = *(((long*)buf1) + i) * *(((long*)buf2) + i); 
      }
    } else if(op == MPI_LAND) {
      for(i=0; i<count; i++) {
        *(((long*)buf3) + i) = *(((long*)buf1) + i) && *(((long*)buf2) + i); 
      }
    } else if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((long*)buf3) + i) = *(((long*)buf1) + i) & *(((long*)buf2) + i); 
      }
    } else if(op == MPI_LOR) {
      for(i=0; i<count; i++) {
        *(((long*)buf3) + i) = *(((long*)buf1) + i) || *(((long*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((long*)buf3) + i) = *(((long*)buf1) + i) | *(((long*)buf2) + i); 
      }
    } else if(op == MPI_LXOR) {
      for(i=0; i<count; i++) {
        *(((long*)buf3) + i) = ((*(((long*)buf1) + i) ? 1 : 0) ^ (*(((long*)buf2) + i) ?  1 : 0)); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((long*)buf3) + i) = ((*(((long*)buf1) + i)) ^ (*(((long*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_LONG_LONG) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((long long*)buf1) + i) > *(((long long*)buf2) + i)) *(((long long*)buf3) + i) = *(((long long*)buf2) + i); else *(((long long*)buf3) + i) = *(((long long*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((long long*)buf1) + i) < *(((long long*)buf2) + i)) *(((long long*)buf3) + i) = *(((long long*)buf2) + i); else *(((long long*)buf3) + i) = *(((long long*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((long long*)buf3) + i) = *(((long long*)buf1) + i) + *(((long long*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((long long*)buf3) + i) = *(((long long*)buf1) + i) * *(((long long*)buf2) + i); 
      }
    } else if(op == MPI_LAND) {
      for(i=0; i<count; i++) {
        *(((long long*)buf3) + i) = *(((long long*)buf1) + i) && *(((long long*)buf2) + i); 
      }
    } else if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((long long*)buf3) + i) = *(((long long*)buf1) + i) & *(((long long*)buf2) + i); 
      }
    } else if(op == MPI_LOR) {
      for(i=0; i<count; i++) {
        *(((long long*)buf3) + i) = *(((long long*)buf1) + i) || *(((long long*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((long long*)buf3) + i) = *(((long long*)buf1) + i) | *(((long long*)buf2) + i); 
      }
    } else if(op == MPI_LXOR) {
      for(i=0; i<count; i++) {
        *(((long long*)buf3) + i) = ((*(((long long*)buf1) + i) ? 1 : 0) ^ (*(((long long*)buf2) + i) ?  1 : 0)); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((long long*)buf3) + i) = ((*(((long long*)buf1) + i)) ^ (*(((long long*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_LONG_LONG_INT) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((long long int*)buf1) + i) > *(((long long int*)buf2) + i)) *(((long long int*)buf3) + i) = *(((long long int*)buf2) + i); else *(((long long int*)buf3) + i) = *(((long long int*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((long long int*)buf1) + i) < *(((long long int*)buf2) + i)) *(((long long int*)buf3) + i) = *(((long long int*)buf2) + i); else *(((long long int*)buf3) + i) = *(((long long int*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((long long int*)buf3) + i) = *(((long long int*)buf1) + i) + *(((long long int*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((long long int*)buf3) + i) = *(((long long int*)buf1) + i) * *(((long long int*)buf2) + i); 
      }
    } else if(op == MPI_LAND) {
      for(i=0; i<count; i++) {
        *(((long long int*)buf3) + i) = *(((long long int*)buf1) + i) && *(((long long int*)buf2) + i); 
      }
    } else if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((long long int*)buf3) + i) = *(((long long int*)buf1) + i) & *(((long long int*)buf2) + i); 
      }
    } else if(op == MPI_LOR) {
      for(i=0; i<count; i++) {
        *(((long long int*)buf3) + i) = *(((long long int*)buf1) + i) || *(((long long int*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((long long int*)buf3) + i) = *(((long long int*)buf1) + i) | *(((long long int*)buf2) + i); 
      }
    } else if(op == MPI_LXOR) {
      for(i=0; i<count; i++) {
        *(((long long int*)buf3) + i) = ((*(((long long int*)buf1) + i) ? 1 : 0) ^ (*(((long long int*)buf2) + i) ?  1 : 0)); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((long long int*)buf3) + i) = ((*(((long long int*)buf1) + i)) ^ (*(((long long int*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_SHORT) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((short*)buf1) + i) > *(((short*)buf2) + i)) *(((short*)buf3) + i) = *(((short*)buf2) + i); else *(((short*)buf3) + i) = *(((short*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((short*)buf1) + i) < *(((short*)buf2) + i)) *(((short*)buf3) + i) = *(((short*)buf2) + i); else *(((short*)buf3) + i) = *(((short*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((short*)buf3) + i) = *(((short*)buf1) + i) + *(((short*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((short*)buf3) + i) = *(((short*)buf1) + i) * *(((short*)buf2) + i); 
      }
    } else if(op == MPI_LAND) {
      for(i=0; i<count; i++) {
        *(((short*)buf3) + i) = *(((short*)buf1) + i) && *(((short*)buf2) + i); 
      }
    } else if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((short*)buf3) + i) = *(((short*)buf1) + i) & *(((short*)buf2) + i); 
      }
    } else if(op == MPI_LOR) {
      for(i=0; i<count; i++) {
        *(((short*)buf3) + i) = *(((short*)buf1) + i) || *(((short*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((short*)buf3) + i) = *(((short*)buf1) + i) | *(((short*)buf2) + i); 
      }
    } else if(op == MPI_LXOR) {
      for(i=0; i<count; i++) {
        *(((short*)buf3) + i) = ((*(((short*)buf1) + i) ? 1 : 0) ^ (*(((short*)buf2) + i) ?  1 : 0)); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((short*)buf3) + i) = ((*(((short*)buf1) + i)) ^ (*(((short*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_UNSIGNED) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((unsigned int*)buf1) + i) > *(((unsigned int*)buf2) + i)) *(((unsigned int*)buf3) + i) = *(((unsigned int*)buf2) + i); else *(((unsigned int*)buf3) + i) = *(((unsigned int*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((unsigned int*)buf1) + i) < *(((unsigned int*)buf2) + i)) *(((unsigned int*)buf3) + i) = *(((unsigned int*)buf2) + i); else *(((unsigned int*)buf3) + i) = *(((unsigned int*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((unsigned int*)buf3) + i) = *(((unsigned int*)buf1) + i) + *(((unsigned int*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((unsigned int*)buf3) + i) = *(((unsigned int*)buf1) + i) * *(((unsigned int*)buf2) + i); 
      }
    } else if(op == MPI_LAND) {
      for(i=0; i<count; i++) {
        *(((unsigned int*)buf3) + i) = *(((unsigned int*)buf1) + i) && *(((unsigned int*)buf2) + i); 
      }
    } else if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((unsigned int*)buf3) + i) = *(((unsigned int*)buf1) + i) & *(((unsigned int*)buf2) + i); 
      }
    } else if(op == MPI_LOR) {
      for(i=0; i<count; i++) {
        *(((unsigned int*)buf3) + i) = *(((unsigned int*)buf1) + i) || *(((unsigned int*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((unsigned int*)buf3) + i) = *(((unsigned int*)buf1) + i) | *(((unsigned int*)buf2) + i); 
      }
    } else if(op == MPI_LXOR) {
      for(i=0; i<count; i++) {
        *(((unsigned int*)buf3) + i) = ((*(((unsigned int*)buf1) + i) ? 1 : 0) ^ (*(((unsigned int*)buf2) + i) ?  1 : 0)); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((unsigned int*)buf3) + i) = ((*(((unsigned int*)buf1) + i)) ^ (*(((unsigned int*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_UNSIGNED_LONG) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((unsigned long*)buf1) + i) > *(((unsigned long*)buf2) + i)) *(((unsigned long*)buf3) + i) = *(((unsigned long*)buf2) + i); else *(((unsigned long*)buf3) + i) = *(((unsigned long*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((unsigned long*)buf1) + i) < *(((unsigned long*)buf2) + i)) *(((unsigned long*)buf3) + i) = *(((unsigned long*)buf2) + i); else *(((unsigned long*)buf3) + i) = *(((unsigned long*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((unsigned long*)buf3) + i) = *(((unsigned long*)buf1) + i) + *(((unsigned long*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((unsigned long*)buf3) + i) = *(((unsigned long*)buf1) + i) * *(((unsigned long*)buf2) + i); 
      }
    } else if(op == MPI_LAND) {
      for(i=0; i<count; i++) {
        *(((unsigned long*)buf3) + i) = *(((unsigned long*)buf1) + i) && *(((unsigned long*)buf2) + i); 
      }
    } else if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((unsigned long*)buf3) + i) = *(((unsigned long*)buf1) + i) & *(((unsigned long*)buf2) + i); 
      }
    } else if(op == MPI_LOR) {
      for(i=0; i<count; i++) {
        *(((unsigned long*)buf3) + i) = *(((unsigned long*)buf1) + i) || *(((unsigned long*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((unsigned long*)buf3) + i) = *(((unsigned long*)buf1) + i) | *(((unsigned long*)buf2) + i); 
      }
    } else if(op == MPI_LXOR) {
      for(i=0; i<count; i++) {
        *(((unsigned long*)buf3) + i) = ((*(((unsigned long*)buf1) + i) ? 1 : 0) ^ (*(((unsigned long*)buf2) + i) ?  1 : 0)); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((unsigned long*)buf3) + i) = ((*(((unsigned long*)buf1) + i)) ^ (*(((unsigned long*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_UNSIGNED_LONG_LONG) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((unsigned long long*)buf1) + i) > *(((unsigned long long*)buf2) + i)) *(((unsigned long long*)buf3) + i) = *(((unsigned long long*)buf2) + i); else *(((unsigned long long*)buf3) + i) = *(((unsigned long long*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((unsigned long long*)buf1) + i) < *(((unsigned long long*)buf2) + i)) *(((unsigned long long*)buf3) + i) = *(((unsigned long long*)buf2) + i); else *(((unsigned long long*)buf3) + i) = *(((unsigned long long*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((unsigned long long*)buf3) + i) = *(((unsigned long long*)buf1) + i) + *(((unsigned long long*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((unsigned long long*)buf3) + i) = *(((unsigned long long*)buf1) + i) * *(((unsigned long long*)buf2) + i); 
      }
    } else if(op == MPI_LAND) {
      for(i=0; i<count; i++) {
        *(((unsigned long long*)buf3) + i) = *(((unsigned long long*)buf1) + i) && *(((unsigned long long*)buf2) + i); 
      }
    } else if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((unsigned long long*)buf3) + i) = *(((unsigned long long*)buf1) + i) & *(((unsigned long long*)buf2) + i); 
      }
    } else if(op == MPI_LOR) {
      for(i=0; i<count; i++) {
        *(((unsigned long long*)buf3) + i) = *(((unsigned long long*)buf1) + i) || *(((unsigned long long*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((unsigned long long*)buf3) + i) = *(((unsigned long long*)buf1) + i) | *(((unsigned long long*)buf2) + i); 
      }
    } else if(op == MPI_LXOR) {
      for(i=0; i<count; i++) {
        *(((unsigned long long*)buf3) + i) = ((*(((unsigned long long*)buf1) + i) ? 1 : 0) ^ (*(((unsigned long long*)buf2) + i) ?  1 : 0)); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((unsigned long long*)buf3) + i) = ((*(((unsigned long long*)buf1) + i)) ^ (*(((unsigned long long*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_UNSIGNED_SHORT) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((unsigned short*)buf1) + i) > *(((unsigned short*)buf2) + i)) *(((unsigned short*)buf3) + i) = *(((unsigned short*)buf2) + i); else *(((unsigned short*)buf3) + i) = *(((unsigned short*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((unsigned short*)buf1) + i) < *(((unsigned short*)buf2) + i)) *(((unsigned short*)buf3) + i) = *(((unsigned short*)buf2) + i); else *(((unsigned short*)buf3) + i) = *(((unsigned short*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((unsigned short*)buf3) + i) = *(((unsigned short*)buf1) + i) + *(((unsigned short*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((unsigned short*)buf3) + i) = *(((unsigned short*)buf1) + i) * *(((unsigned short*)buf2) + i); 
      }
    } else if(op == MPI_LAND) {
      for(i=0; i<count; i++) {
        *(((unsigned short*)buf3) + i) = *(((unsigned short*)buf1) + i) && *(((unsigned short*)buf2) + i); 
      }
    } else if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((unsigned short*)buf3) + i) = *(((unsigned short*)buf1) + i) & *(((unsigned short*)buf2) + i); 
      }
    } else if(op == MPI_LOR) {
      for(i=0; i<count; i++) {
        *(((unsigned short*)buf3) + i) = *(((unsigned short*)buf1) + i) || *(((unsigned short*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((unsigned short*)buf3) + i) = *(((unsigned short*)buf1) + i) | *(((unsigned short*)buf2) + i); 
      }
    } else if(op == MPI_LXOR) {
      for(i=0; i<count; i++) {
        *(((unsigned short*)buf3) + i) = ((*(((unsigned short*)buf1) + i) ? 1 : 0) ^ (*(((unsigned short*)buf2) + i) ?  1 : 0)); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((unsigned short*)buf3) + i) = ((*(((unsigned short*)buf1) + i)) ^ (*(((unsigned short*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else
#ifdef MPI_INT8_T
if(type == MPI_INT8_T) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((int8_t*)buf1) + i) > *(((int8_t*)buf2) + i)) *(((int8_t*)buf3) + i) = *(((int8_t*)buf2) + i); else *(((int8_t*)buf3) + i) = *(((int8_t*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((int8_t*)buf1) + i) < *(((int8_t*)buf2) + i)) *(((int8_t*)buf3) + i) = *(((int8_t*)buf2) + i); else *(((int8_t*)buf3) + i) = *(((int8_t*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((int8_t*)buf3) + i) = *(((int8_t*)buf1) + i) + *(((int8_t*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((int8_t*)buf3) + i) = *(((int8_t*)buf1) + i) * *(((int8_t*)buf2) + i); 
      }
    } else if(op == MPI_LAND) {
      for(i=0; i<count; i++) {
        *(((int8_t*)buf3) + i) = *(((int8_t*)buf1) + i) && *(((int8_t*)buf2) + i); 
      }
    } else if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((int8_t*)buf3) + i) = *(((int8_t*)buf1) + i) & *(((int8_t*)buf2) + i); 
      }
    } else if(op == MPI_LOR) {
      for(i=0; i<count; i++) {
        *(((int8_t*)buf3) + i) = *(((int8_t*)buf1) + i) || *(((int8_t*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((int8_t*)buf3) + i) = *(((int8_t*)buf1) + i) | *(((int8_t*)buf2) + i); 
      }
    } else if(op == MPI_LXOR) {
      for(i=0; i<count; i++) {
        *(((int8_t*)buf3) + i) = ((*(((int8_t*)buf1) + i) ? 1 : 0) ^ (*(((int8_t*)buf2) + i) ?  1 : 0)); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((int8_t*)buf3) + i) = ((*(((int8_t*)buf1) + i)) ^ (*(((int8_t*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else
#endif
#ifdef MPI_INT16_T
if(type == MPI_INT16_T) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((int16_t*)buf1) + i) > *(((int16_t*)buf2) + i)) *(((int16_t*)buf3) + i) = *(((int16_t*)buf2) + i); else *(((int16_t*)buf3) + i) = *(((int16_t*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((int16_t*)buf1) + i) < *(((int16_t*)buf2) + i)) *(((int16_t*)buf3) + i) = *(((int16_t*)buf2) + i); else *(((int16_t*)buf3) + i) = *(((int16_t*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((int16_t*)buf3) + i) = *(((int16_t*)buf1) + i) + *(((int16_t*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((int16_t*)buf3) + i) = *(((int16_t*)buf1) + i) * *(((int16_t*)buf2) + i); 
      }
    } else if(op == MPI_LAND) {
      for(i=0; i<count; i++) {
        *(((int16_t*)buf3) + i) = *(((int16_t*)buf1) + i) && *(((int16_t*)buf2) + i); 
      }
    } else if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((int16_t*)buf3) + i) = *(((int16_t*)buf1) + i) & *(((int16_t*)buf2) + i); 
      }
    } else if(op == MPI_LOR) {
      for(i=0; i<count; i++) {
        *(((int16_t*)buf3) + i) = *(((int16_t*)buf1) + i) || *(((int16_t*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((int16_t*)buf3) + i) = *(((int16_t*)buf1) + i) | *(((int16_t*)buf2) + i); 
      }
    } else if(op == MPI_LXOR) {
      for(i=0; i<count; i++) {
        *(((int16_t*)buf3) + i) = ((*(((int16_t*)buf1) + i) ? 1 : 0) ^ (*(((int16_t*)buf2) + i) ?  1 : 0)); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((int16_t*)buf3) + i) = ((*(((int16_t*)buf1) + i)) ^ (*(((int16_t*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else
#endif
#ifdef MPI_INT32_T
if(type == MPI_INT32_T) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((int32_t*)buf1) + i) > *(((int32_t*)buf2) + i)) *(((int32_t*)buf3) + i) = *(((int32_t*)buf2) + i); else *(((int32_t*)buf3) + i) = *(((int32_t*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((int32_t*)buf1) + i) < *(((int32_t*)buf2) + i)) *(((int32_t*)buf3) + i) = *(((int32_t*)buf2) + i); else *(((int32_t*)buf3) + i) = *(((int32_t*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((int32_t*)buf3) + i) = *(((int32_t*)buf1) + i) + *(((int32_t*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((int32_t*)buf3) + i) = *(((int32_t*)buf1) + i) * *(((int32_t*)buf2) + i); 
      }
    } else if(op == MPI_LAND) {
      for(i=0; i<count; i++) {
        *(((int32_t*)buf3) + i) = *(((int32_t*)buf1) + i) && *(((int32_t*)buf2) + i); 
      }
    } else if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((int32_t*)buf3) + i) = *(((int32_t*)buf1) + i) & *(((int32_t*)buf2) + i); 
      }
    } else if(op == MPI_LOR) {
      for(i=0; i<count; i++) {
        *(((int32_t*)buf3) + i) = *(((int32_t*)buf1) + i) || *(((int32_t*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((int32_t*)buf3) + i) = *(((int32_t*)buf1) + i) | *(((int32_t*)buf2) + i); 
      }
    } else if(op == MPI_LXOR) {
      for(i=0; i<count; i++) {
        *(((int32_t*)buf3) + i) = ((*(((int32_t*)buf1) + i) ? 1 : 0) ^ (*(((int32_t*)buf2) + i) ?  1 : 0)); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((int32_t*)buf3) + i) = ((*(((int32_t*)buf1) + i)) ^ (*(((int32_t*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else
#endif
#ifdef MPI_INT64_T
if(type == MPI_INT64_T) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((int64_t*)buf1) + i) > *(((int64_t*)buf2) + i)) *(((int64_t*)buf3) + i) = *(((int64_t*)buf2) + i); else *(((int64_t*)buf3) + i) = *(((int64_t*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((int64_t*)buf1) + i) < *(((int64_t*)buf2) + i)) *(((int64_t*)buf3) + i) = *(((int64_t*)buf2) + i); else *(((int64_t*)buf3) + i) = *(((int64_t*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((int64_t*)buf3) + i) = *(((int64_t*)buf1) + i) + *(((int64_t*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((int64_t*)buf3) + i) = *(((int64_t*)buf1) + i) * *(((int64_t*)buf2) + i); 
      }
    } else if(op == MPI_LAND) {
      for(i=0; i<count; i++) {
        *(((int64_t*)buf3) + i) = *(((int64_t*)buf1) + i) && *(((int64_t*)buf2) + i); 
      }
    } else if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((int64_t*)buf3) + i) = *(((int64_t*)buf1) + i) & *(((int64_t*)buf2) + i); 
      }
    } else if(op == MPI_LOR) {
      for(i=0; i<count; i++) {
        *(((int64_t*)buf3) + i) = *(((int64_t*)buf1) + i) || *(((int64_t*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((int64_t*)buf3) + i) = *(((int64_t*)buf1) + i) | *(((int64_t*)buf2) + i); 
      }
    } else if(op == MPI_LXOR) {
      for(i=0; i<count; i++) {
        *(((int64_t*)buf3) + i) = ((*(((int64_t*)buf1) + i) ? 1 : 0) ^ (*(((int64_t*)buf2) + i) ?  1 : 0)); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((int64_t*)buf3) + i) = ((*(((int64_t*)buf1) + i)) ^ (*(((int64_t*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else
#endif
#ifdef MPI_UINT8_T
if(type == MPI_UINT8_T) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((uint8_t*)buf1) + i) > *(((uint8_t*)buf2) + i)) *(((uint8_t*)buf3) + i) = *(((uint8_t*)buf2) + i); else *(((uint8_t*)buf3) + i) = *(((uint8_t*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((uint8_t*)buf1) + i) < *(((uint8_t*)buf2) + i)) *(((uint8_t*)buf3) + i) = *(((uint8_t*)buf2) + i); else *(((uint8_t*)buf3) + i) = *(((uint8_t*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((uint8_t*)buf3) + i) = *(((uint8_t*)buf1) + i) + *(((uint8_t*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((uint8_t*)buf3) + i) = *(((uint8_t*)buf1) + i) * *(((uint8_t*)buf2) + i); 
      }
    } else if(op == MPI_LAND) {
      for(i=0; i<count; i++) {
        *(((uint8_t*)buf3) + i) = *(((uint8_t*)buf1) + i) && *(((uint8_t*)buf2) + i); 
      }
    } else if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((uint8_t*)buf3) + i) = *(((uint8_t*)buf1) + i) & *(((uint8_t*)buf2) + i); 
      }
    } else if(op == MPI_LOR) {
      for(i=0; i<count; i++) {
        *(((uint8_t*)buf3) + i) = *(((uint8_t*)buf1) + i) || *(((uint8_t*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((uint8_t*)buf3) + i) = *(((uint8_t*)buf1) + i) | *(((uint8_t*)buf2) + i); 
      }
    } else if(op == MPI_LXOR) {
      for(i=0; i<count; i++) {
        *(((uint8_t*)buf3) + i) = ((*(((uint8_t*)buf1) + i) ? 1 : 0) ^ (*(((uint8_t*)buf2) + i) ?  1 : 0)); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((uint8_t*)buf3) + i) = ((*(((uint8_t*)buf1) + i)) ^ (*(((uint8_t*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else
#endif
#ifdef MPI_UINT16_T
if(type == MPI_UINT16_T) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((uint16_t*)buf1) + i) > *(((uint16_t*)buf2) + i)) *(((uint16_t*)buf3) + i) = *(((uint16_t*)buf2) + i); else *(((uint16_t*)buf3) + i) = *(((uint16_t*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((uint16_t*)buf1) + i) < *(((uint16_t*)buf2) + i)) *(((uint16_t*)buf3) + i) = *(((uint16_t*)buf2) + i); else *(((uint16_t*)buf3) + i) = *(((uint16_t*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((uint16_t*)buf3) + i) = *(((uint16_t*)buf1) + i) + *(((uint16_t*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((uint16_t*)buf3) + i) = *(((uint16_t*)buf1) + i) * *(((uint16_t*)buf2) + i); 
      }
    } else if(op == MPI_LAND) {
      for(i=0; i<count; i++) {
        *(((uint16_t*)buf3) + i) = *(((uint16_t*)buf1) + i) && *(((uint16_t*)buf2) + i); 
      }
    } else if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((uint16_t*)buf3) + i) = *(((uint16_t*)buf1) + i) & *(((uint16_t*)buf2) + i); 
      }
    } else if(op == MPI_LOR) {
      for(i=0; i<count; i++) {
        *(((uint16_t*)buf3) + i) = *(((uint16_t*)buf1) + i) || *(((uint16_t*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((uint16_t*)buf3) + i) = *(((uint16_t*)buf1) + i) | *(((uint16_t*)buf2) + i); 
      }
    } else if(op == MPI_LXOR) {
      for(i=0; i<count; i++) {
        *(((uint16_t*)buf3) + i) = ((*(((uint16_t*)buf1) + i) ? 1 : 0) ^ (*(((uint16_t*)buf2) + i) ?  1 : 0)); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((uint16_t*)buf3) + i) = ((*(((uint16_t*)buf1) + i)) ^ (*(((uint16_t*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else
#endif
#ifdef MPI_UINT32_T
if(type == MPI_UINT32_T) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((uint32_t*)buf1) + i) > *(((uint32_t*)buf2) + i)) *(((uint32_t*)buf3) + i) = *(((uint32_t*)buf2) + i); else *(((uint32_t*)buf3) + i) = *(((uint32_t*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((uint32_t*)buf1) + i) < *(((uint32_t*)buf2) + i)) *(((uint32_t*)buf3) + i) = *(((uint32_t*)buf2) + i); else *(((uint32_t*)buf3) + i) = *(((uint32_t*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((uint32_t*)buf3) + i) = *(((uint32_t*)buf1) + i) + *(((uint32_t*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((uint32_t*)buf3) + i) = *(((uint32_t*)buf1) + i) * *(((uint32_t*)buf2) + i); 
      }
    } else if(op == MPI_LAND) {
      for(i=0; i<count; i++) {
        *(((uint32_t*)buf3) + i) = *(((uint32_t*)buf1) + i) && *(((uint32_t*)buf2) + i); 
      }
    } else if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((uint32_t*)buf3) + i) = *(((uint32_t*)buf1) + i) & *(((uint32_t*)buf2) + i); 
      }
    } else if(op == MPI_LOR) {
      for(i=0; i<count; i++) {
        *(((uint32_t*)buf3) + i) = *(((uint32_t*)buf1) + i) || *(((uint32_t*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((uint32_t*)buf3) + i) = *(((uint32_t*)buf1) + i) | *(((uint32_t*)buf2) + i); 
      }
    } else if(op == MPI_LXOR) {
      for(i=0; i<count; i++) {
        *(((uint32_t*)buf3) + i) = ((*(((uint32_t*)buf1) + i) ? 1 : 0) ^ (*(((uint32_t*)buf2) + i) ?  1 : 0)); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((uint32_t*)buf3) + i) = ((*(((uint32_t*)buf1) + i)) ^ (*(((uint32_t*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else
#endif
#ifdef MPI_UINT64_T
if(type == MPI_UINT64_T) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((uint64_t*)buf1) + i) > *(((uint64_t*)buf2) + i)) *(((uint64_t*)buf3) + i) = *(((uint64_t*)buf2) + i); else *(((uint64_t*)buf3) + i) = *(((uint64_t*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((uint64_t*)buf1) + i) < *(((uint64_t*)buf2) + i)) *(((uint64_t*)buf3) + i) = *(((uint64_t*)buf2) + i); else *(((uint64_t*)buf3) + i) = *(((uint64_t*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((uint64_t*)buf3) + i) = *(((uint64_t*)buf1) + i) + *(((uint64_t*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((uint64_t*)buf3) + i) = *(((uint64_t*)buf1) + i) * *(((uint64_t*)buf2) + i); 
      }
    } else if(op == MPI_LAND) {
      for(i=0; i<count; i++) {
        *(((uint64_t*)buf3) + i) = *(((uint64_t*)buf1) + i) && *(((uint64_t*)buf2) + i); 
      }
    } else if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((uint64_t*)buf3) + i) = *(((uint64_t*)buf1) + i) & *(((uint64_t*)buf2) + i); 
      }
    } else if(op == MPI_LOR) {
      for(i=0; i<count; i++) {
        *(((uint64_t*)buf3) + i) = *(((uint64_t*)buf1) + i) || *(((uint64_t*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((uint64_t*)buf3) + i) = *(((uint64_t*)buf1) + i) | *(((uint64_t*)buf2) + i); 
      }
    } else if(op == MPI_LXOR) {
      for(i=0; i<count; i++) {
        *(((uint64_t*)buf3) + i) = ((*(((uint64_t*)buf1) + i) ? 1 : 0) ^ (*(((uint64_t*)buf2) + i) ?  1 : 0)); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((uint64_t*)buf3) + i) = ((*(((uint64_t*)buf1) + i)) ^ (*(((uint64_t*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else
#endif
if(type == MPI_FLOAT) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((float*)buf1) + i) > *(((float*)buf2) + i)) *(((float*)buf3) + i) = *(((float*)buf2) + i); else *(((float*)buf3) + i) = *(((float*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((float*)buf1) + i) < *(((float*)buf2) + i)) *(((float*)buf3) + i) = *(((float*)buf2) + i); else *(((float*)buf3) + i) = *(((float*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((float*)buf3) + i) = *(((float*)buf1) + i) + *(((float*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((float*)buf3) + i) = *(((float*)buf1) + i) * *(((float*)buf2) + i); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_DOUBLE) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((double*)buf1) + i) > *(((double*)buf2) + i)) *(((double*)buf3) + i) = *(((double*)buf2) + i); else *(((double*)buf3) + i) = *(((double*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((double*)buf1) + i) < *(((double*)buf2) + i)) *(((double*)buf3) + i) = *(((double*)buf2) + i); else *(((double*)buf3) + i) = *(((double*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((double*)buf3) + i) = *(((double*)buf1) + i) + *(((double*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((double*)buf3) + i) = *(((double*)buf1) + i) * *(((double*)buf2) + i); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_LONG_DOUBLE) { 
    if(op == MPI_MIN) {
      for(i=0; i<count; i++) {
        if(*(((long double*)buf1) + i) > *(((long double*)buf2) + i)) *(((long double*)buf3) + i) = *(((long double*)buf2) + i); else *(((long double*)buf3) + i) = *(((long double*)buf1) + i); 
      }
    } else if(op == MPI_MAX) {
      for(i=0; i<count; i++) {
        if(*(((long double*)buf1) + i) < *(((long double*)buf2) + i)) *(((long double*)buf3) + i) = *(((long double*)buf2) + i); else *(((long double*)buf3) + i) = *(((long double*)buf1) + i); 
      }
    } else if(op == MPI_SUM) {
      for(i=0; i<count; i++) {
        *(((long double*)buf3) + i) = *(((long double*)buf1) + i) + *(((long double*)buf2) + i); 
      }
    } else if(op == MPI_PROD) {
      for(i=0; i<count; i++) {
        *(((long double*)buf3) + i) = *(((long double*)buf1) + i) * *(((long double*)buf2) + i); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_BYTE) { 
    if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((char*)buf3) + i) = *(((char*)buf1) + i) & *(((char*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((char*)buf3) + i) = *(((char*)buf1) + i) | *(((char*)buf2) + i); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((char*)buf3) + i) = ((*(((char*)buf1) + i)) ^ (*(((char*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_CHAR) { 
    if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((char*)buf3) + i) = *(((char*)buf1) + i) & *(((char*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((char*)buf3) + i) = *(((char*)buf1) + i) | *(((char*)buf2) + i); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((char*)buf3) + i) = ((*(((char*)buf1) + i)) ^ (*(((char*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_SIGNED_CHAR) { 
    if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((signed char*)buf3) + i) = *(((signed char*)buf1) + i) & *(((signed char*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((signed char*)buf3) + i) = *(((signed char*)buf1) + i) | *(((signed char*)buf2) + i); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((signed char*)buf3) + i) = ((*(((signed char*)buf1) + i)) ^ (*(((signed char*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_UNSIGNED_CHAR) { 
    if(op == MPI_BAND) {
      for(i=0; i<count; i++) {
        *(((unsigned char*)buf3) + i) = *(((unsigned char*)buf1) + i) & *(((unsigned char*)buf2) + i); 
      }
    } else if(op == MPI_BOR) {
      for(i=0; i<count; i++) {
        *(((unsigned char*)buf3) + i) = *(((unsigned char*)buf1) + i) | *(((unsigned char*)buf2) + i); 
      }
    } else if(op == MPI_BXOR) {
      for(i=0; i<count; i++) {
        *(((unsigned char*)buf3) + i) = ((*(((unsigned char*)buf1) + i)) ^ (*(((unsigned char*)buf2) + i))); 
      }
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_FLOAT_INT) { 
    if(op == MPI_MAXLOC) {
      for(i=0; i<count; i++) {
        typedef struct {
          float val;
          int rank;
        } float_int;
        float_int *ptr1, *ptr2, *ptr3;
                            
        ptr1 = ((float_int*)buf1) + i;
        ptr2 = ((float_int*)buf2) + i;
        ptr3 = ((float_int*)buf3) + i;
      
        if(ptr1->val < ptr2->val) { 
          ptr3->val = ptr2->val; ptr3->rank = ptr2->rank; 
        } else { 
          ptr3->val = ptr1->val; ptr3->rank = ptr1->rank; 
        } 
      }  
    } else if(op == MPI_MINLOC) {
      for(i=0; i<count; i++) {
        typedef struct {
          float val;
          int rank;
        } float_int;
        float_int *ptr1, *ptr2, *ptr3;
                            
        ptr1 = ((float_int*)buf1) + i;
        ptr2 = ((float_int*)buf2) + i;
        ptr3 = ((float_int*)buf3) + i;
      
        if(ptr1->val > ptr2->val) { 
          ptr3->val = ptr2->val; ptr3->rank = ptr2->rank; 
        } else { 
          ptr3->val = ptr1->val; ptr3->rank = ptr1->rank; 
        } 
      }  
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_DOUBLE_INT) { 
    if(op == MPI_MAXLOC) {
      for(i=0; i<count; i++) {
        typedef struct {
          double val;
          int rank;
        } double_int;
        double_int *ptr1, *ptr2, *ptr3;
                            
        ptr1 = ((double_int*)buf1) + i;
        ptr2 = ((double_int*)buf2) + i;
        ptr3 = ((double_int*)buf3) + i;
      
        if(ptr1->val < ptr2->val) { 
          ptr3->val = ptr2->val; ptr3->rank = ptr2->rank; 
        } else { 
          ptr3->val = ptr1->val; ptr3->rank = ptr1->rank; 
        } 
      }  
    } else if(op == MPI_MINLOC) {
      for(i=0; i<count; i++) {
        typedef struct {
          double val;
          int rank;
        } double_int;
        double_int *ptr1, *ptr2, *ptr3;
                            
        ptr1 = ((double_int*)buf1) + i;
        ptr2 = ((double_int*)buf2) + i;
        ptr3 = ((double_int*)buf3) + i;
      
        if(ptr1->val > ptr2->val) { 
          ptr3->val = ptr2->val; ptr3->rank = ptr2->rank; 
        } else { 
          ptr3->val = ptr1->val; ptr3->rank = ptr1->rank; 
        } 
      }  
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_LONG_INT) { 
    if(op == MPI_MAXLOC) {
      for(i=0; i<count; i++) {
        typedef struct {
          long val;
          int rank;
        } long_int;
        long_int *ptr1, *ptr2, *ptr3;
                            
        ptr1 = ((long_int*)buf1) + i;
        ptr2 = ((long_int*)buf2) + i;
        ptr3 = ((long_int*)buf3) + i;
      
        if(ptr1->val < ptr2->val) { 
          ptr3->val = ptr2->val; ptr3->rank = ptr2->rank; 
        } else { 
          ptr3->val = ptr1->val; ptr3->rank = ptr1->rank; 
        } 
      }  
    } else if(op == MPI_MINLOC) {
      for(i=0; i<count; i++) {
        typedef struct {
          long val;
          int rank;
        } long_int;
        long_int *ptr1, *ptr2, *ptr3;
                            
        ptr1 = ((long_int*)buf1) + i;
        ptr2 = ((long_int*)buf2) + i;
        ptr3 = ((long_int*)buf3) + i;
      
        if(ptr1->val > ptr2->val) { 
          ptr3->val = ptr2->val; ptr3->rank = ptr2->rank; 
        } else { 
          ptr3->val = ptr1->val; ptr3->rank = ptr1->rank; 
        } 
      }  
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_2INT) { 
    if(op == MPI_MAXLOC) {
      for(i=0; i<count; i++) {
        typedef struct {
          int val;
          int rank;
        } int_int;
        int_int *ptr1, *ptr2, *ptr3;
                            
        ptr1 = ((int_int*)buf1) + i;
        ptr2 = ((int_int*)buf2) + i;
        ptr3 = ((int_int*)buf3) + i;
      
        if(ptr1->val < ptr2->val) { 
          ptr3->val = ptr2->val; ptr3->rank = ptr2->rank; 
        } else { 
          ptr3->val = ptr1->val; ptr3->rank = ptr1->rank; 
        } 
      }  
    } else if(op == MPI_MINLOC) {
      for(i=0; i<count; i++) {
        typedef struct {
          int val;
          int rank;
        } int_int;
        int_int *ptr1, *ptr2, *ptr3;
                            
        ptr1 = ((int_int*)buf1) + i;
        ptr2 = ((int_int*)buf2) + i;
        ptr3 = ((int_int*)buf3) + i;
      
        if(ptr1->val > ptr2->val) { 
          ptr3->val = ptr2->val; ptr3->rank = ptr2->rank; 
        } else { 
          ptr3->val = ptr1->val; ptr3->rank = ptr1->rank; 
        } 
      }  
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_SHORT_INT) { 
    if(op == MPI_MAXLOC) {
      for(i=0; i<count; i++) {
        typedef struct {
          short val;
          int rank;
        } short_int;
        short_int *ptr1, *ptr2, *ptr3;
                            
        ptr1 = ((short_int*)buf1) + i;
        ptr2 = ((short_int*)buf2) + i;
        ptr3 = ((short_int*)buf3) + i;
      
        if(ptr1->val < ptr2->val) { 
          ptr3->val = ptr2->val; ptr3->rank = ptr2->rank; 
        } else { 
          ptr3->val = ptr1->val; ptr3->rank = ptr1->rank; 
        } 
      }  
    } else if(op == MPI_MINLOC) {
      for(i=0; i<count; i++) {
        typedef struct {
          short val;
          int rank;
        } short_int;
        short_int *ptr1, *ptr2, *ptr3;
                            
        ptr1 = ((short_int*)buf1) + i;
        ptr2 = ((short_int*)buf2) + i;
        ptr3 = ((short_int*)buf3) + i;
      
        if(ptr1->val > ptr2->val) { 
          ptr3->val = ptr2->val; ptr3->rank = ptr2->rank; 
        } else { 
          ptr3->val = ptr1->val; ptr3->rank = ptr1->rank; 
        } 
      }  
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else if(type == MPI_LONG_DOUBLE_INT) { 
    if(op == MPI_MAXLOC) {
      for(i=0; i<count; i++) {
        typedef struct {
          long double val;
          int rank;
        } long_double_int;
        long_double_int *ptr1, *ptr2, *ptr3;
                            
        ptr1 = ((long_double_int*)buf1) + i;
        ptr2 = ((long_double_int*)buf2) + i;
        ptr3 = ((long_double_int*)buf3) + i;
      
        if(ptr1->val < ptr2->val) { 
          ptr3->val = ptr2->val; ptr3->rank = ptr2->rank; 
        } else { 
          ptr3->val = ptr1->val; ptr3->rank = ptr1->rank; 
        } 
      }  
    } else if(op == MPI_MINLOC) {
      for(i=0; i<count; i++) {
        typedef struct {
          long double val;
          int rank;
        } long_double_int;
        long_double_int *ptr1, *ptr2, *ptr3;
                            
        ptr1 = ((long_double_int*)buf1) + i;
        ptr2 = ((long_double_int*)buf2) + i;
        ptr3 = ((long_double_int*)buf3) + i;
      
        if(ptr1->val > ptr2->val) { 
          ptr3->val = ptr2->val; ptr3->rank = ptr2->rank; 
        } else { 
          ptr3->val = ptr1->val; ptr3->rank = ptr1->rank; 
        } 
      }  
    } else MPI_Abort(MPI_COMM_WORLD, NBC_OP_NOT_SUPPORTED); 
  } else MPI_Abort(MPI_COMM_WORLD, NBC_DATATYPE_NOT_SUPPORTED);
  
  return NBC_OK;
}
